/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useRef, useState, useEffect } from 'react';
import { Card, Input, Button, Avatar, Typography, Space, Tag, message, Table, Empty, Tooltip, Divider, Select } from 'antd';
import { SendOutlined, UserOutlined, RobotOutlined, DatabaseOutlined, CodeOutlined, ThunderboltOutlined } from '@ant-design/icons';
import { theme } from 'antd';

const { Text } = Typography;
const { TextArea } = Input;

interface ChatMessage {
  id: string;
  role: 'user' | 'assistant';
  content: string;
  sql?: string;
  data?: any;
  executionTime?: number;
  rowCount?: number;
  columns?: { name: string; comment?: string }[];
}

const ChatPage: React.FC = () => {
  const { token } = theme.useToken();
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [input, setInput] = useState('');
  const [loading, setLoading] = useState(false);
  const listRef = useRef<HTMLDivElement | null>(null);
  const [dbType, setDbType] = useState<'mysql' | 'postgresql' | 'sqlite'>('mysql');
  const [streaming, setStreaming] = useState(false);
  const [logs, setLogs] = useState<string[]>([]);

  const API_BASE = (import.meta as any).env?.VITE_API_BASE || 'http://localhost:8000';

  const columns = [
    { title: '字段', dataIndex: 'key', key: 'key', width: 160 },
    { title: '值', dataIndex: 'value', key: 'value' },
  ];

  const sendMessage = async () => {
    const query = input.trim();
    if (!query) {
      message.warning('请输入查询需求');
      return;
    }
    const userMsg: ChatMessage = { id: Date.now() + '-u', role: 'user', content: query };
    setMessages(prev => [...prev, userMsg]);
    setInput('');
    setLoading(true);
    try {
      const resp = await fetch(`${API_BASE}/api/query/natural-language`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ query, database_type: dbType }),
      });
      if (!resp.ok) throw new Error('请求失败');
      const json = await resp.json();
      const assistantMsg: ChatMessage = {
        id: Date.now() + '-a',
        role: 'assistant',
        content: json?.message || '查询完成',
        sql: json?.sql_generated,
        data: json?.data,
        executionTime: json?.execution_time,
        rowCount: json?.row_count,
        columns: json?.columns,
      };
      setMessages(prev => [...prev, assistantMsg]);
    } catch (e: any) {
      message.error(e?.message || '调用失败');
      const errMsg: ChatMessage = { id: Date.now() + '-e', role: 'assistant', content: '调用失败，请检查后端服务' };
      setMessages(prev => [...prev, errMsg]);
    } finally {
      setLoading(false);
    }
  };

  const sendStreaming = async () => {
    const query = input.trim();
    if (!query) {
      message.warning('请输入查询需求');
      return;
    }
    const userMsg: ChatMessage = { id: Date.now() + '-u', role: 'user', content: query };
    setMessages(prev => [...prev, userMsg]);
    setInput('');
    setStreaming(true);
    setLogs([]);
    try {
      const resp = await fetch(`${API_BASE}/api/analysis/stream`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ query }),
      });
      if (!resp.ok || !resp.body) throw new Error('流式接口不可用');
      const reader = resp.body.getReader();
      const decoder = new TextDecoder('utf-8');
      let buffer = '';
      while (true) {
        const { value, done } = await reader.read();
        if (done) break;
        buffer += decoder.decode(value, { stream: true });
        const parts = buffer.split('\n\n');
        buffer = parts.pop() || '';
        for (const part of parts) {
          const lines = part.split('\n');
          let event = 'message';
          let data = '';
          for (const line of lines) {
            if (line.startsWith('event:')) event = line.slice(6).trim();
            if (line.startsWith('data:')) data += line.slice(5).trim();
          }
                     if (event === 'intent') setLogs(prev => [...prev, '解析: ' + data]);
           if (event === 'context') setLogs(prev => [...prev, '上下文: ' + data]);
           if (event === 'sql') {
             try {
               const sqlData = JSON.parse(data);
               if (sqlData.sql && sqlData.sql.includes('重试SQL:')) {
                 setLogs(prev => [...prev, '重试SQL: ' + sqlData.sql]);
               } else {
                 setLogs(prev => [...prev, 'SQL: ' + data]);
               }
             } catch {
               setLogs(prev => [...prev, 'SQL: ' + data]);
             }
           }
           if (event === 'exec') {
             try {
               const execData = JSON.parse(data);
               if (execData.message && execData.message.includes('重新生成SQL')) {
                 setLogs(prev => [...prev, '重试: ' + data]);
               } else {
                 setLogs(prev => [...prev, '执行: ' + data]);
               }
             } catch {
               setLogs(prev => [...prev, '执行: ' + data]);
             }
           }
                     if (event === 'final') {
             try {
               const payload = JSON.parse(data);
               const json = payload?.data || {};
               setLogs(prev => [...prev, `完成: 返回 ${json?.row_count || 0} 行数据`]);
               const assistantMsg: ChatMessage = {
                 id: Date.now() + '-a',
                 role: 'assistant',
                 content: '分析完成',
                 sql: json?.sql,
                 data: json?.data,
                 rowCount: json?.row_count,
                 columns: json?.columns,
               };
               setMessages(prev => [...prev, assistantMsg]);
             } catch (err) {
               console.error(err);
             }
           }
          if (event === 'error') setLogs(prev => [...prev, '错误: ' + data]);
        }
      }
    } catch (e: any) {
      message.error(e?.message || '流式调用失败');
    } finally {
      setStreaming(false);
    }
  };

  // 回车发送，Shift+Enter 换行
  const onKeyDown: React.KeyboardEventHandler<HTMLTextAreaElement> = (e) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      if (!loading) sendMessage();
    }
  };

  // 新消息自动滚动到底部
  useEffect(() => {
    if (listRef.current) {
      listRef.current.scrollTop = listRef.current.scrollHeight;
    }
  }, [messages]);

  const renderAssistantContent = (m: ChatMessage) => {
    const hasTableArray = Array.isArray(m.data) && m.data.length > 0 && typeof m.data[0] === 'object';
    return (
      <Space direction="vertical" style={{ width: '100%' }} size="small">
        <Text>{m.content}</Text>
        {m.sql && (
          <Tag icon={<CodeOutlined />} color="blue">{m.sql}</Tag>
        )}
        {(m.executionTime || m.rowCount) && (
          <Text type="secondary">用时 {m.executionTime ? m.executionTime.toFixed?.(2) : '-'}s · 行数 {m.rowCount ?? '-'}</Text>
        )}
        {hasTableArray && (
          (() => {
            const firstRowKeys = Object.keys(m.data[0]);
            const colMap: Record<string, string> = Object.fromEntries(
              (m.columns || []).map(c => [c.name, (c.comment && String(c.comment).trim()) || c.name])
            );
            const tblCols = firstRowKeys.map((k: string) => ({
              title: colMap[k] && colMap[k] !== k ? (
                <Tooltip title={k}>{colMap[k]}</Tooltip>
              ) : (
                k
              ),
              dataIndex: k,
              key: k,
            }));
            return (
              <Table
                size="small"
                rowKey="id"
                columns={tblCols}
                dataSource={m.data}
                pagination={{ pageSize: 10 }}
                scroll={{ x: true }}
              />
            );
          })()
        )}
        {!hasTableArray && m.data && typeof m.data === 'object' && (
          <Table
            size="small"
            rowKey="key"
            columns={columns}
            dataSource={Object.entries(m.data).map(([key, value]) => ({ key, value: typeof value === 'object' ? JSON.stringify(value) : value }))}
            pagination={false}
          />
        )}
      </Space>
    );
  };

  return (
    <div
      style={{
        minHeight: '100vh',
        background: `radial-gradient(60% 120% at 10% 10%, ${token.colorPrimary}14 0%, transparent 50%), radial-gradient(60% 120% at 90% 0%, ${token.cyan}14 0%, transparent 50%), linear-gradient(180deg, ${token.colorBgLayout} 0%, ${token.colorBgElevated} 100%)`,
        padding: 24,
      }}
    >
      <Card
        style={{
          maxWidth: 1100,
          margin: '0 auto',
          boxShadow: '0 10px 40px rgba(0,0,0,0.12)',
          borderRadius: 16,
          backdropFilter: 'blur(6px)',
        }}
        bodyStyle={{ padding: 0 }}
      >
        {/* Header */}
        <div style={{
          padding: '20px 24px',
          borderBottom: `1px solid ${token.colorSplit}`,
          display: 'flex',
          alignItems: 'center',
          gap: 12,
          background: `linear-gradient(90deg, ${token.colorPrimary}10, transparent)`
        }}>
          <div style={{
            width: 40,
            height: 40,
            borderRadius: 10,
            display: 'grid',
            placeItems: 'center',
            background: `linear-gradient(135deg, ${token.colorPrimary}, ${token.cyan})`,
            color: '#fff'
          }}>
            <ThunderboltOutlined />
          </div>
          <div>
            <Typography.Title level={4} style={{ margin: 0 }}>聊天查询</Typography.Title>
            <Typography.Text type="secondary">用自然语言向 Agent 提问并查询数据库</Typography.Text>
          </div>
          <div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 8 }}>
            <Select
              size="small"
              value={dbType}
              onChange={(v) => setDbType(v)}
              options={[
                { label: 'MySQL', value: 'mysql' },
                { label: 'PostgreSQL', value: 'postgresql' },
                { label: 'SQLite', value: 'sqlite' },
              ]}
              style={{ width: 130 }}
            />
            <Tooltip title={`接口：${API_BASE}/api/query/natural-language`}>
              <DatabaseOutlined />
            </Tooltip>
          </div>
        </div>

        {/* Messages */}
        <div ref={listRef} style={{ padding: 24, maxHeight: '62vh', overflowY: 'auto' }}>
          {messages.length === 0 ? (
            <Empty description={<span>暂无数据</span>} />
          ) : (
            <div>
              {messages.map((m) => {
                const isUser = m.role === 'user';
                return (
                  <div key={m.id} style={{ display: 'flex', marginBottom: 16, justifyContent: isUser ? 'flex-end' : 'flex-start' }}>
                    {!isUser && (
                      <Avatar style={{ background: token.colorPrimary, marginRight: 12 }} icon={<RobotOutlined />} />
                    )}
                    <div
                      style={{
                        maxWidth: '72%',
                        background: isUser ? token.colorPrimary : token.colorBgContainer,
                        color: isUser ? '#fff' : token.colorText,
                        borderRadius: isUser ? '12px 12px 4px 12px' : '12px 12px 12px 4px',
                        padding: 12,
                        boxShadow: '0 6px 20px rgba(0,0,0,0.06)'
                      }}
                    >
                      {isUser ? (
                        <Text style={{ color: '#fff' }}>{m.content}</Text>
                      ) : (
                        renderAssistantContent(m)
                      )}
                    </div>
                    {isUser && (
                      <Avatar style={{ background: token.cyan, marginLeft: 12 }} icon={<UserOutlined />} />
                    )}
                  </div>
                );
              })}
            </div>
          )}
        </div>

        <Divider style={{ margin: 0 }} />

        {/* Input */}
        <div style={{ padding: 16, position: 'sticky', bottom: 0, background: token.colorBgElevated, borderRadius: '0 0 16px 16px' }}>
          <Space direction="vertical" style={{ width: '100%' }} size="small">
            <TextArea
              rows={3}
              value={input}
              onChange={(e) => setInput(e.target.value)}
              onKeyDown={onKeyDown}
              placeholder="例如：查询最近30天的订单数量（Enter 发送 / Shift+Enter 换行）"
            />
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <Typography.Text type="secondary">Enter 发送（REST），或使用流式</Typography.Text>
              <Space>
                <Button onClick={sendStreaming} disabled={!input.trim()} loading={streaming}>流式</Button>
                <Button type="primary" icon={<SendOutlined />} onClick={sendMessage} loading={loading} disabled={!input.trim()}>
                发送
                </Button>
              </Space>
            </div>
          </Space>
        </div>
      </Card>
      {!!logs.length && (
        <Card style={{ maxWidth: 1100, margin: '12px auto 0' }} size="small" title="过程日志">
          <div style={{ whiteSpace: 'pre-wrap' }}>{logs.join('\n')}</div>
        </Card>
      )}
    </div>
  );
};

export default ChatPage;


